package com.njlime.core.web.api;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.njlime.core.exception.BusinessException;
import com.njlime.core.exception.ExceptionState;
import com.njlime.core.exception.FormatException;
import com.njlime.core.exception.WebException;
import com.njlime.core.utils.MapUtil;
import com.njlime.sys.security.util.CacheUtils;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 统一接口处理服务
 * Created by Dean on 2018-3-19.
 */
public class ApiHandleServlet extends HttpServlet{

    private static final Logger logger = Logger.getLogger(ApiHandleServlet.class);

    public ApiHandleServlet(){
        super();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=utf-8"); //指定返回的格式为JSON格式
        response.setCharacterEncoding("UTF-8"); //setContentType与setCharacterEncoding的顺序不能调换，否则还是无法解决中文乱码的问题
        PrintWriter out = response.getWriter();
        JSONObject result = new JSONObject();
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                stringBuilder.append(line);
            }
            logger.info("接口收到数据：" + stringBuilder.toString());
            Map<String, Object> data = null;
            if(isJson(stringBuilder.toString())){
                data = JSONObject.parseObject(stringBuilder.toString());
            }else if(isXML(stringBuilder.toString())){
                data = MapUtil.xmlString2Map(stringBuilder.toString());
            }else{
                throw new FormatException("数据格式异常，请使用json或者xml格式");
            }
            logger.info("转化后数据：" + data);
            //获取接口数据
            JSONObject api;
            try{
                api = (JSONObject) ((Map<String,Object>) CacheUtils.get("api")).get(data.get("apiCode"));
            }catch (Exception e){
                throw new BusinessException("接口不存在，请重新确认");
            }
            //获取接口方法
            Class cls = Class.forName(api.getString("path"));
            //利用反射方式获取相应的方法（非静态）
            Method method = cls.getMethod(api.getString("method"), Map.class);
            //执行获取到的方法
            result = (JSONObject) method.invoke(cls.newInstance(), data);
            out.write(result.toJSONString());
        }catch (Exception e){
            logger.error(e);
            if(e instanceof WebException){
                result.put("resCode", ((WebException) e).getExceptionCode());
                result.put("message", e.getMessage());
            }else{
                result.put("resCode", ExceptionState.UNKNOWN_EXCEPTION);
                result.put("message", "未知异常，请联系接口提供方");
            }
            out.write(result.toJSONString());
        }finally {
            if(out != null) {
                out.close();
            }
        }
    }

    public void destroy(){
        super.destroy();
    }

    /**
     * 判断是否是json结构
     */
    private static boolean isJson(String value) {
        try {
            JSONObject.parseObject(value);
        } catch (JSONException e) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否是xml结构
     */
    private static boolean isXML(String value) {
        try {
            DocumentHelper.parseText(value);
        } catch (DocumentException e) {
            return false;
        }
        return true;
    }

}
